package utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author LiangHaiBo
 * @version 1.0
 * @date 2021.8.31 上午 7:56
 */
public class JdbcUtils {
    private  static DataSource ds ;
    private static ThreadLocal<Connection>  t1 = new ThreadLocal<>() ; //提供线程的局部变量保存连接对象
    //构造方法私有化
    private JdbcUtils(){}

    //静态代码块
    static{
        try {
            //读取数据库连接池的配置文件----->通过DruidDataSourceFactory工厂类创建DataSource
            //创建一个属性集合列表
            Properties prop = new Properties() ;
            //读取druid.properties
            InputStream inputStream = JdbcUtils.class.getClassLoader().
                    getResourceAsStream("jdbc.properties");

            //将资源文件所在的输入流加载列表中
            prop.load(inputStream);
            ds = DruidDataSourceFactory.createDataSource(prop); //底层子实现类:DruidDataSource
            //System.out.println("数据源获取成功");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //提供静态方法:单独获取数据源
    public static DataSource getDataSource(){
        return ds ;
    }


    //获取连接对象Connection静态功能

    public static Connection getConnection(){
        //从ThreadLocal中获取局部变量的副本:Connection
        /**
         *   public T get()  :从线程中获取局部变量的副本!
         */
        Connection conn =  null ;
        try {
            conn  =  t1.get();
            if(conn==null){
                //如果空,需要从数据库的连接池中获取连接对象
                conn  = ds.getConnection();
                //获取到之后,每一线程执行自己的Connection
                //将获取到的连接对象 绑定到当前线程中
                t1.set(conn);
            }
            //如果不为空,说明ThreadLocal线程中已经存在Connection
            return conn ; //
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null ;

    }

    //关闭(释放资源)资源
    public static void close(ResultSet rs, Statement stmt, Connection conn)  {
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
                //关闭之后,归还到连接池中,需要从当前线程中解绑
                t1.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void close(Statement stmt, Connection conn)  {
        close(null,stmt,conn);
    }

    //事务管理代码 --- 加入

    /*public static void main(String[] args) {
        // DataSource ds = DruidJdbcUtils.getDataSource();
        //System.out.println(ds);


        Connection connection = JdbcUtils.getConnection();
        System.out.println(connection);
    }*/
    //事务管理代码 --- 加入
    //开启事务
    public static void startTransacton() throws SQLException {
        //获取连接对象
        getConnection().setAutoCommit(false); //禁用自动提交
    }

    //提交事务并且关闭
    public static void commitAndClose() throws SQLException {
        //获取连接对象
        Connection connection = getConnection();
        //提交事务
        connection.commit();
        //释放资源:归还到连接池中
        connection.close();
        //从线程中解绑
        t1.remove();

    }

    //事务回滚并且关闭
    public static void rollbackAndClose() throws SQLException {
        //获取连接对象
        Connection connection = getConnection();
        //提交事务
        connection.rollback();
        //释放资源:归还到连接池中
        connection.close();
        //从线程中解绑
        t1.remove();
    }

}
